package com.jbm;

import com.rsa.cmbVerifyTools;
import com.sun.net.httpserver.HttpServer;
import net.sf.json.JSONObject;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;

/**
 * Created by root on 18-5-31.
 */
public class GServer
{
	public static int Server_Type_Gate = 0;
	public static int Server_Type_Control = 1;
	public static int g_server_type;

	public static void main(String[] args) throws IOException
	{
		JSONObject jObj= JSONObject.fromObject("{\"id\":\"120103197011206148\",\"method\":\"get_door_list\",\"mobile\":\"13802192434\",\"door1\":\"444444\"}");
		System.out.println("??:"+jObj);

		String sign= cmbVerifyTools.cmbSign("private.key",jObj);
		System.out.println("Sign:"+sign);

		boolean iss = cmbVerifyTools.cmbVerify("public.key",jObj,sign);
		System.out.println("iss:"+iss);

		SysLog.g_syslog.Init("gdserver.log",31,31);

		String run_type = null;
		String wy_code = null;
		String db_name = null;

		for ( String arg:args)
		{
			switch (arg.substring(0,2))
			{
				case "-r":
				{
					run_type = arg.substring(2);
					break;
				}
				case "-w":
				{
					wy_code = arg.substring(2);
					break;
				}
				case "-d":
				{
					db_name = arg.substring(2);
					break;
				}
				default:
					break;
			}
		}

		if ( run_type == null ||
				run_type.equals("control") && ( wy_code == null ||
						db_name == null ) )
		{
			SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_ERROR,"-rXXX run_type(control or gate)\n" +
					"-wXXX wy_code\n" +
					"-dXXX db_name");
			return;
		}

		try
		{
			Class.forName("com.mysql.jdbc.Driver");

			for ( int i = 0; i < 20; i ++ )
			{
				Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/"+db_name+"?"
						+ "user=root&password=password&useUnicode=true&characterEncoding=UTF8");

				if ( GDHandler.db_pool == null )
					GDHandler.db_pool = new ArrayBlockingQueue(20);

				GDHandler.db_pool.put(conn);
			}
		}catch (Exception e)
		{
			SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_ERROR,"%s",e.getMessage());
		}

		if ( run_type.equals("control") )
			g_server_type = Server_Type_Control;
		else if ( run_type.equals("gate"))
			g_server_type = Server_Type_Gate;
		else
		{
			SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_ERROR,"wrong run_type(control or gate)");
			return;
		}

		if ( g_server_type == Server_Type_Control )
		{
			try
			{
				DoProcess dp = (DoProcess)Class.forName("com.jbm."+wy_code).newInstance();
				dp.Begin();
			}catch (Exception e)
			{
				SysLog.g_syslog.MakeLog(SysLog.SYS_LOG_LEVEL_ERROR,"DoProcess.Begin() error\n" +
						"%s",e.getMessage());

				return;
			}

			ConnectAgent ca = new ConnectAgent(0,
					InetAddress.getByName("app.jiabangmang.com").getHostAddress(),
					1990,0,ConnectAgent.CA_Type_Json_Client,2000);

			ca.wy_code = wy_code;
			ca.Born(3,5000);
			ca.ConnectServer();
			ca.setM_keepalive(true);

			BridgeHnadler.b_client_ca.put(wy_code,ca);
			BridgeHnadler.b_pool.Add(ca);
		}else
		{
			IoAcceptor acceptor = new NioSocketAcceptor();
			acceptor.getFilterChain().addLast("logger", new LoggingFilter());
			acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new JSONCodeFactory("UTF-8")));
			acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
			// 设置读取数据的缓冲区大小
			acceptor.getSessionConfig().setReadBufferSize(4096);
			// 读写通道10秒内无操作进入空闲状态
			acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
			acceptor.setHandler(new BridgeHnadler());
			acceptor.bind(new InetSocketAddress(1990));

			HttpServer server = HttpServer.create(new InetSocketAddress(8001), 0);
			server.createContext("/test", new HttpHandler());
			server.setExecutor(Executors.newCachedThreadPool());
			server.start();

			HttpServer unpayserver = HttpServer.create(new InetSocketAddress(8008), 0);
			unpayserver.createContext("/unpay", new UPHttpHandler());
			unpayserver.setExecutor(Executors.newCachedThreadPool());
			unpayserver.start();
		}
	}
}

class GServerHandle extends IoHandlerAdapter
{
	protected static Logger logger = LoggerFactory.getLogger(GServerHandle.class);

	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		cause.printStackTrace();
	}

	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {

		logger.info("Recv...");
//		byte[] rtn = {0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x49, 0x43, 0x02, 0x43, 0x36, 0x34, 0x38, 0x0D};
//		session.write(rtn);

		byte[] msg = (byte[])message;

		if ( msg.length == 38 )
		{
			byte[] open = {0x01, 0x30, 0x33, 0x34, 0x30, 0x30, 0x30, 0x30, 0x4A, 0x41,
					0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
					0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
					0x30, 0x31, 0x02,
//					0x38, 0x31, 0x41, 0x35,
					0x30, 0x30, 0x30, 0x30,
					0x0d
			};
			session.write(Guard.getOpenCMD(0x34,14));
		}
	}

	@Override
	public void sessionCreated(IoSession session) throws Exception
	{
		logger.info("客户端与服务端创建连接...port:" + ((InetSocketAddress) session.getRemoteAddress()).getPort());
	}
}
